"""
热点数据模型定义
"""
from datetime import datetime, timedelta, timezone
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field, validator
from enum import Enum


class Platform(str, Enum):
    """支持的平台枚举"""
    WEIBO = "weibo"
    ZHIHU = "zhihu"
    TOUTIAO = "toutiao"
    BAIDU = "baidu"
    XIAOHONGSHU = "xiaohongshu"
    DOUYIN = "douyin"
    BILIBILI = "bilibili"
    WEIXIN = "weixin"
    JUEJIN = "juejin"
    V2EX = "v2ex"
    TIEBA = "tieba"
    DOUBAN = "douban"
    HUPU = "hupu"
    GITHUB = "github"
    # 保留但暂时不使用（TopHub不支持）
    TWITTER = "twitter"
    REDDIT = "reddit"
    YOUTUBE = "youtube"


class SortOrder(str, Enum):
    """排序方式枚举"""
    ASC = "asc"
    DESC = "desc"


class SortBy(str, Enum):
    """排序字段枚举"""
    HEAT = "heat_value"
    TIME = "crawled_at"
    RANK = "rank"
    PLATFORM = "platform"


class TrendDirection(str, Enum):
    """趋势方向枚举"""
    UP = "up"
    DOWN = "down"
    STABLE = "stable"
    NEW = "new"
    OUT = "out"


class PaginationParams(BaseModel):
    """分页参数模型"""
    page: int = Field(1, ge=1, description="页码")
    page_size: int = Field(20, ge=1, le=100, description="每页大小")
    
    @validator("page_size")
    def validate_page_size(cls, v):
        if v > 100:
            raise ValueError("page_size不能超过100")
        return v


class FilterParams(BaseModel):
    """筛选参数模型"""
    platforms: Optional[List[Platform]] = Field(None, description="平台列表")
    time_range: Optional[str] = Field(None, description="时间范围（latest/today/week/month）")
    start_date: Optional[datetime] = Field(None, description="开始时间")
    end_date: Optional[datetime] = Field(None, description="结束时间")
    min_heat: Optional[int] = Field(None, ge=0, description="最小热度值")
    max_rank: Optional[int] = Field(None, ge=1, le=100, description="最大排名")
    category: Optional[str] = Field(None, description="分类")
    
    @validator("end_date")
    def validate_date_range(cls, v, values):
        if v:
            # 检查未来日期 - 允许1小时的时钟偏差
            if v > datetime.now(timezone.utc) + timedelta(hours=1):
                raise ValueError("end_date不能是未来日期")

            # 检查与start_date的关系
            if "start_date" in values and values["start_date"]:
                if v < values["start_date"]:
                    raise ValueError("end_date不能早于start_date")
        return v

    @validator("start_date")
    def validate_start_date(cls, v):
        # 允许1小时的时钟偏差
        if v and v > datetime.now(timezone.utc) + timedelta(hours=1):
            raise ValueError("start_date不能是未来日期")
        return v
    
    def __init__(self, **data):
        """初始化时处理time_range"""
        if "time_range" in data and data["time_range"]:
            time_range = data["time_range"]
            now = datetime.now(timezone.utc)
            
            if time_range == "latest":
                if "start_date" not in data or not data["start_date"]:
                    data["start_date"] = now - timedelta(hours=2)
                if "end_date" not in data or not data["end_date"]:
                    data["end_date"] = now
            elif time_range == "today":
                if "start_date" not in data or not data["start_date"]:
                    data["start_date"] = datetime(now.year, now.month, now.day)
                if "end_date" not in data or not data["end_date"]:
                    data["end_date"] = now
            elif time_range == "week":
                if "start_date" not in data or not data["start_date"]:
                    data["start_date"] = now - timedelta(days=7)
                if "end_date" not in data or not data["end_date"]:
                    data["end_date"] = now
            elif time_range == "month":
                if "start_date" not in data or not data["start_date"]:
                    data["start_date"] = now - timedelta(days=30)
                if "end_date" not in data or not data["end_date"]:
                    data["end_date"] = now
        
        super().__init__(**data)


class SortParams(BaseModel):
    """排序参数模型"""
    sort_by: SortBy = Field(SortBy.TIME, description="排序字段（默认按时间，确保显示最新数据）")
    order: SortOrder = Field(SortOrder.DESC, description="排序方向")


class HotItemBase(BaseModel):
    """热点数据基础模型"""
    item_id: str = Field(..., description="项目ID")
    title: str = Field(..., description="标题")
    platform: Platform = Field(..., description="平台")
    rank: int = Field(..., ge=1, description="排名")
    heat_value: str = Field(..., description="热度值")
    heat_value_numeric: Optional[int] = Field(None, description="数值类型的热度值")
    url: str = Field(..., description="原始链接")
    excerpt: Optional[str] = Field(None, description="摘要")
    category: Optional[str] = Field(None, description="分类")
    crawled_at: datetime = Field(..., description="爬取时间")
    updated_at: datetime = Field(..., description="更新时间")


class HotItemDetail(HotItemBase):
    """热点详情模型"""
    content: Optional[str] = Field(None, description="完整内容")
    author_hash: Optional[str] = Field(None, description="作者哈希")
    view_count: Optional[int] = Field(None, description="浏览量")
    comment_count: Optional[int] = Field(None, description="评论数")
    share_count: Optional[int] = Field(None, description="分享数")
    images: Optional[List[str]] = Field(default_factory=list, description="图片列表")
    videos: Optional[List[str]] = Field(default_factory=list, description="视频列表")
    tags: Optional[List[str]] = Field(default_factory=list, description="标签")
    comments: Optional[List[Dict[str, Any]]] = Field(default_factory=list, description="热门评论")
    metadata: Optional[Dict[str, Any]] = Field(default_factory=dict, description="额外元数据")


class HotItemTrend(BaseModel):
    """热点趋势模型"""
    item_id: str = Field(..., description="项目ID")
    title: str = Field(..., description="标题")
    platform: Platform = Field(..., description="平台")
    current_rank: int = Field(..., description="当前排名")
    previous_rank: Optional[int] = Field(None, description="之前排名")
    rank_change: int = Field(0, description="排名变化")
    trend_direction: TrendDirection = Field(..., description="趋势方向")
    heat_values: List[Dict[str, Any]] = Field(..., description="热度值历史")
    first_seen: datetime = Field(..., description="首次出现时间")
    last_seen: datetime = Field(..., description="最后出现时间")
    duration_hours: float = Field(..., description="持续小时数")


class HotItemAggregate(BaseModel):
    """聚合热点模型"""
    title: str = Field(..., description="标题（合并后）")
    platforms: List[Platform] = Field(..., description="出现的平台列表")
    total_heat: int = Field(..., description="总热度值")
    average_rank: float = Field(..., description="平均排名")
    items: List[HotItemBase] = Field(..., description="各平台项目列表")
    similarity_score: float = Field(..., ge=0, le=1, description="相似度分数")
    category: Optional[str] = Field(None, description="分类")


class SearchParams(BaseModel):
    """搜索参数模型"""
    keyword: str = Field(..., min_length=1, max_length=100, description="搜索关键词")
    match_type: str = Field("fuzzy", pattern="^(exact|fuzzy)$", description="匹配类型")
    search_fields: List[str] = Field(
        default=["title", "content", "excerpt"],
        description="搜索字段"
    )
    highlight: bool = Field(True, description="是否高亮")


class BaseResponse(BaseModel):
    """基础响应模型"""
    success: bool = Field(..., description="请求是否成功")
    message: str = Field(..., description="响应消息")
    timestamp: datetime = Field(default_factory=datetime.utcnow, description="响应时间")


class SuccessResponse(BaseResponse):
    """成功响应模型"""
    success: bool = Field(True)
    data: Any = Field(..., description="响应数据")


class ErrorResponse(BaseResponse):
    """错误响应模型"""
    success: bool = Field(False)
    error: Dict[str, Any] = Field(..., description="错误详情")


class PaginatedResponse(SuccessResponse):
    """分页响应模型"""
    data: Dict[str, Any] = Field(..., description="包含items和pagination")
    
    @validator("data")
    def validate_pagination_data(cls, v):
        if "items" not in v or "pagination" not in v:
            raise ValueError("分页响应必须包含items和pagination")
        return v


class HotItemListResponse(BaseModel):
    """热点列表响应"""
    items: List[HotItemBase]
    pagination: Dict[str, Any] = Field(..., description="分页信息")


class HotItemSearchResponse(BaseModel):
    """搜索响应"""
    items: List[HotItemBase]
    total: int = Field(..., description="总匹配数")
    keyword: str = Field(..., description="搜索关键词")
    highlights: Optional[Dict[str, List[str]]] = Field(None, description="高亮片段")


class HotItemTrendResponse(BaseModel):
    """趋势响应"""
    trends: List[HotItemTrend]
    period: str = Field(..., description="统计周期")
    platform: Optional[Platform] = Field(None, description="平台")
    summary: Dict[str, Any] = Field(..., description="趋势摘要")


class HotItemAggregateResponse(BaseModel):
    """聚合响应"""
    aggregates: List[HotItemAggregate]
    total_items: int = Field(..., description="总项目数")
    platforms_included: List[Platform] = Field(..., description="包含的平台")
    aggregation_time: datetime = Field(..., description="聚合时间")
    deduplication_count: int = Field(0, description="去重数量")